#pragma once
#include <map>
#include <string>
#include "interfaces.h"
#include "tinyxml2.h"

class Actor
{
	friend class ActorFactory;

	typedef std::map<ComponentId, StrongActorComponentPtr> ActorComponents;

	ActorId m_id;
	std::string m_type;
	ActorComponents m_components;

public:
	explicit Actor(ActorId id);
	~Actor();

	bool Init(tinyxml2::XMLElement* pData);
	void PostInit();
	void Destroy();
	void Update(double deltaSecs);

	ActorId GetId() const { return m_id; }

	template <class ComponentType>
	std::weak_ptr<ComponentType> GetComponent(ComponentId id)
	{
		ActorComponents::iterator findIt = m_components.find(id);
		if(findIt != m_components.end())
		{
			StrongActorComponentPtr pBase(findIt->second);
			std::shared_ptr<ComponentType> pSub(
				std::tr1::static_pointer_cast<ComponentType>(pBase));
			std::weak_ptr<ComponentType> pWeakSub(pSub);
			return pWeakSub; 
		}
		else
		{
			return std::weak_ptr<ComponentType>();
		}
	}

private:
	void AddComponent(StrongActorComponentPtr pComponent);
};